Set up
suppressPackageStartupMessages({
library(tidyverse)
})
Read in data and process
# Vector to order timepoints
timepoints <- c("Diagnosis", "Progressive", "Recurrence", "xDeceased", "Second Malignancy", "Unavailable")
pbta_df <- readr::read_tsv(pbta_file, guess_max = 100000, show_col_types = FALSE) %>%
select(Kids_First_Participant_ID, Kids_First_Biospecimen_ID, cg_multiple, cg_id, cgGFAC, tumor_descriptor)
tmb_vaf_df <- readr::read_tsv(tmb_vaf_file, guess_max = 100000, show_col_types = FALSE) %>%
filter(!tmb >= 10) %>%
select(Kids_First_Biospecimen_ID, Variant_Classification, gene_protein, mutation_count, region_size, tmb, VAF)
genomic_paired_df <- readr::read_tsv(genomic_paired_file, guess_max = 100000, show_col_types = FALSE) %>%
left_join(pbta_df, by = c("Kids_First_Participant_ID")) %>%
left_join(tmb_vaf_df, by = c("Kids_First_Biospecimen_ID")) %>%
filter(!is.na(tmb))
no_samples_with_tmb <- print(length(unique(genomic_paired_df$Kids_First_Participant_ID)))
[1] 116
# Attention as some bs specimen might not have TMB.
# If that happens, we will end up with samples lacking timepoints.
# Let's identify these samples and remove them for now.
df <- genomic_paired_df %>%
select(Kids_First_Participant_ID, tumor_descriptor) %>%
unique() %>%
arrange(Kids_First_Participant_ID, tumor_descriptor) %>%
group_by(Kids_First_Participant_ID) %>%
summarize(tumor_descriptor_sum = str_c(tumor_descriptor, collapse = ";")) %>%
filter(!tumor_descriptor_sum %in% c("Diagnosis", "Progressive", "Recurrence", "Second Malignancy", "Unavailable", "Deceased", "Progressive;Progressive")) %>%
left_join(genomic_paired_df, by = c("Kids_First_Participant_ID")) %>%
filter(!cg_id == "NA") %>%
mutate(tumor_descriptor = case_when(grepl("Deceased", tumor_descriptor) ~ "xDeceased",
TRUE ~ tumor_descriptor),
match_id = paste(tumor_descriptor, Kids_First_Participant_ID, sep = "_"),
tumor_descriptor = factor(tumor_descriptor),
tumor_descriptor = fct_relevel(tumor_descriptor, timepoints))
Warning: There was 1 warning in `mutate()`.
ℹ In argument: `tumor_descriptor = fct_relevel(tumor_descriptor, timepoints)`.
Caused by warning:
! 1 unknown level in `f`: Unavailable
no_samples <- print(length(unique(df$Kids_First_Participant_ID)))
[1] 107
# Let's count number of samples
count_df <- df %>%
group_by(tumor_descriptor, cg_id, match_id, Variant_Classification) %>%
dplyr::count(cg_id)
Define parameters for plots
# Read color palette
palette_df <- readr::read_tsv(palette_file, guess_max = 100000, show_col_types = FALSE)
# Define and order palette
palette <- palette_df$hex_codes
names(palette) <- palette_df$color_names
Alterations per timepoint
# Define parameters for function
x_value <- count_df$tumor_descriptor
title <- paste("Variant types in PBTA cohort", sep = " ")
# Run function
fname <- paste0(plots_dir, "/", "Alteration_type_timepoints_barplots.pdf")
print(fname)
[1] "/Users/chronia/CHOP/GitHub/pbta-tumor-evolution/analyses/tmb-vaf-longitudinal/plots/Alteration_type_timepoints_barplots.pdf"
p <- create_stacked_barplot_variant(count_df = count_df, x = x_value, palette = palette, title = title)
pdf(file = fname, width = 6, height = 6)
print(p)
dev.off()
quartz_off_screen
2

Alterations per timepoint in each cancer type

Alterations per timepoint in each cancer type and kids_id
cg_id_id <- as.character(unique(count_df$cg_id))
cg_id_id <- sort(cg_id_id, decreasing = FALSE)
cg_id_id
[1] "Adamantinomatous Craniopharyngioma" "Atypical Teratoid Rhabdoid Tumor" "Chordoma"
[4] "Choroid plexus carcinoma" "CNS Embryonal tumor" "Craniopharyngioma"
[7] "Diffuse midline glioma" "Dysembryoplastic neuroepithelial tumor" "Embryonal tumor with multilayer rosettes"
[10] "Ependymoma" "Ewing sarcoma" "Ganglioglioma"
[13] "Glial-neuronal tumor" "Hemangioblastoma" "High-grade glioma"
[16] "Low-grade glioma" "Malignant peripheral nerve sheath tumor" "Medulloblastoma"
[19] "Meningioma" "Neuroblastoma" "Neurofibroma/Plexiform"
[22] "Pilocytic astrocytoma" "Schwannoma"
# Define parameters for function
x_value <- count_df$match_id
title <- paste("Variant types in PBTA cohort across cancer groups", sep = " ")
# Run function
fname <- paste0(plots_dir, "/", "Alteration_type_timepoints_cg_id_kids_barplots.pdf")
print(fname)
[1] "/Users/chronia/CHOP/GitHub/pbta-tumor-evolution/analyses/tmb-vaf-longitudinal/plots/Alteration_type_timepoints_cg_id_kids_barplots.pdf"
p <- create_stacked_barplot_variant_cg_id(count_df = count_df, x = x_value, palette = palette, title = title)
pdf(file = fname, width = 30, height = 30)
print(p)
dev.off()
quartz_off_screen
2

Alterations per timepoint in each cancer type and timepoint
model
tm_df_plot <- df %>%
filter(!is.na(timepoints_models)) %>%
group_by(tumor_descriptor, cg_id, timepoints_models, match_id, Variant_Classification) %>%
dplyr::count(cg_id)
tm <- as.character(unique(tm_df_plot$timepoints_models))
tm <- sort(tm, decreasing = FALSE)
tm
[1] "Dx-Dec" "Dx-Pro" "Dx-Pro-Dec" "Dx-Pro-Rec" "Dx-Pro-Rec-Dec" "Dx-Rec" "Dx-Rec-Dec" "Dx-SM"
[9] "Pro-Dec" "Pro-Rec" "Pro-Rec-Dec" "Rec-Dec" "Rec-SM"
# Loop through variable
for (i in seq_along(tm)){
print(i)
df_sub <- tm_df_plot %>%
filter(timepoints_models == tm[i])
# Define parameters for function
x_value <- df_sub$match_id
title <- paste(tm[i])
if (i %in% c(1,2,6)){
rows <- 2
}else{
rows <- 1
}
# Run function
p <- create_stacked_barplot_variant_cg_id(count_df = df_sub, x = x_value, palette = palette, title = title, rows = rows)
}
[1] 1
[1] 2
[1] 3
[1] 4
[1] 5
[1] 6
[1] 7
[1] 8
[1] 9
[1] 10
[1] 11
[1] 12
[1] 13













sessionInfo()
R version 4.2.3 (2023-03-15)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Ventura 13.5.2
Matrix products: default
LAPACK: /Library/Frameworks/R.framework/Versions/4.2-arm64/Resources/lib/libRlapack.dylib
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] grid stats graphics grDevices utils datasets methods base
other attached packages:
[1] flextable_0.9.2 ggthemes_4.2.4 lubridate_1.9.2 forcats_1.0.0 stringr_1.5.0 dplyr_1.1.2 purrr_1.0.1 readr_2.1.4
[9] tidyr_1.3.0 tibble_3.2.1 ggplot2_3.4.2 tidyverse_2.0.0
loaded via a namespace (and not attached):
[1] sass_0.4.7 bit64_4.0.5 vroom_1.6.3 jsonlite_1.8.7 carData_3.0-5
[6] bslib_0.5.0 shiny_1.7.4.1 askpass_1.2.0 fontLiberation_0.1.0 yaml_2.3.7
[11] gdtools_0.3.3 pillar_1.9.0 backports_1.4.1 glue_1.6.2 uuid_1.1-0
[16] digest_0.6.33 promises_1.2.0.1 ggsignif_0.6.4 colorspace_2.1-0 htmltools_0.5.5
[21] httpuv_1.6.11 gfonts_0.2.0 fontBitstreamVera_0.1.1 pkgconfig_2.0.3 httpcode_0.3.0
[26] broom_1.0.5 xtable_1.8-4 scales_1.2.1 later_1.3.1 officer_0.6.2
[31] fontquiver_0.2.1 tzdb_0.4.0 openssl_2.1.0 timechange_0.2.0 generics_0.1.3
[36] farver_2.1.1 car_3.1-2 ellipsis_0.3.2 ggpubr_0.6.0 cachem_1.0.8
[41] withr_2.5.0 cli_3.6.1 magrittr_2.0.3 crayon_1.5.2 mime_0.12
[46] evaluate_0.21 fansi_1.0.4 xml2_1.3.5 rstatix_0.7.2 textshaping_0.3.6
[51] tools_4.2.3 data.table_1.14.8 hms_1.1.3 lifecycle_1.0.3 munsell_0.5.0
[56] zip_2.3.0 compiler_4.2.3 jquerylib_0.1.4 systemfonts_1.0.4 rlang_1.1.1
[61] rstudioapi_0.15.0 labeling_0.4.2 rmarkdown_2.23 gtable_0.3.3 abind_1.4-5
[66] curl_5.0.2 R6_2.5.1 knitr_1.43 fastmap_1.1.1 bit_4.0.5
[71] utf8_1.2.3 rprojroot_2.0.3 ragg_1.2.5 stringi_1.7.12 parallel_4.2.3
[76] crul_1.4.0 Rcpp_1.0.11 vctrs_0.6.3 tidyselect_1.2.0 xfun_0.39
LS0tCnRpdGxlOiAiQ2xhc3NpZmljYXRpb24gb2YgVmFyaWFudHMgYWNyb3NzIHBhaXJlZCBsb25naXR1ZGluYWwgc2FtcGxlcyBpbiB0aGUgUEJUQSBDb2hvcnQiCmF1dGhvcjogJ0FudG9uaWEgQ2hyb25pIDxjaHJvbmlhQGNob3AuZWR1PiBmb3IgRDNCJwpkYXRlOiAiMjAyMyIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IFRSVUUKICAgIHRvY19mbG9hdDogVFJVRQotLS0KCiMgU2V0IHVwCmBgYHtyIGxvYWQtbGlicmFyeX0Kc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKHsKICBsaWJyYXJ5KHRpZHl2ZXJzZSkKfSkKYGBgCgojIERpcmVjdG9yaWVzIGFuZCBGaWxlIElucHV0cy9PdXRwdXRzCmBgYHtyIHNldC1kaXItYW5kLWZpbGUtbmFtZXN9CiMgRGV0ZWN0IHRoZSAiLmdpdCIgZm9sZGVyIC0tIHRoaXMgd2lsbCBiZSBpbiB0aGUgcHJvamVjdCByb290IGRpcmVjdG9yeQojIFVzZSB0aGlzIGFzIHRoZSByb290IGRpcmVjdG9yeSB0byBlbnN1cmUgcHJvcGVyIHNvdXJjaW5nIG9mIGZ1bmN0aW9ucyAKIyBubyBtYXR0ZXIgd2hlcmUgdGhpcyBpcyBjYWxsZWQgZnJvbQpyb290X2RpciA8LSBycHJvanJvb3Q6OmZpbmRfcm9vdChycHJvanJvb3Q6Omhhc19kaXIoIi5naXQiKSkKYW5hbHlzaXNfZGlyIDwtIGZpbGUucGF0aChyb290X2RpciwgImFuYWx5c2VzIiwgInRtYi12YWYtbG9uZ2l0dWRpbmFsIikKcmVzdWx0c19kaXIgPC0gZmlsZS5wYXRoKGFuYWx5c2lzX2RpciwgInJlc3VsdHMiKQppbnB1dF9kaXIgPC0gZmlsZS5wYXRoKGFuYWx5c2lzX2RpciwgImlucHV0IikKZmlsZXNfZGlyIDwtIGZpbGUucGF0aChyb290X2RpciwgImFuYWx5c2VzIiwgInNhbXBsZS1kaXN0cmlidXRpb24tYW5hbHlzaXMiLCAicmVzdWx0cyIpCgojIElucHV0IGZpbGVzCnBidGFfZmlsZSA8LSBmaWxlLnBhdGgoZmlsZXNfZGlyLCAicGJ0YS50c3YiKSAjIGZpbGUgZnJvbSBhZGQtc2FtcGxlLWRpc3RyaWJ1dGlvbiBtb2R1bGUKZ2Vub21pY19wYWlyZWRfZmlsZSA8LSBmaWxlLnBhdGgoZmlsZXNfZGlyLCAiZ2Vub21pY19hc3NheXNfbWF0Y2hlZF90aW1lX3BvaW50cy50c3YiKQp0bWJfdmFmX2ZpbGUgPC0gZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAidG1iX3ZhZl9nZW5vbWljLnRzdiIpCnBhbGV0dGVfZmlsZSA8LSBmaWxlLnBhdGgocm9vdF9kaXIsICJmaWd1cmVzIiwgInBhbGV0dGVzIiwgIm9uY29wcmludF9jb2xvcl9wYWxldHRlLnRzdiIpCgojIEZpbGUgcGF0aCB0byBwbG90IGRpcmVjdG9yeQpwbG90c19kaXIgPC0KICBmaWxlLnBhdGgoYW5hbHlzaXNfZGlyLCAicGxvdHMiKQppZiAoIWRpci5leGlzdHMocGxvdHNfZGlyKSkgewogIGRpci5jcmVhdGUocGxvdHNfZGlyKQp9Cgpzb3VyY2UocGFzdGUwKHJvb3RfZGlyLCAiL2ZpZ3VyZXMvc2NyaXB0cy90aGVtZS5SIikpCnNvdXJjZShwYXN0ZTAoYW5hbHlzaXNfZGlyLCAiL3V0aWwvZnVuY3Rpb24tY3JlYXRlLWJhcnBsb3QuUiIpKQpgYGAKCiMgUmVhZCBpbiBkYXRhIGFuZCBwcm9jZXNzCgpgYGB7ciBsb2FkLXByb2Nlc3MtaW5wdXRzfQojIFZlY3RvciB0byBvcmRlciB0aW1lcG9pbnRzCnRpbWVwb2ludHMgPC0gYygiRGlhZ25vc2lzIiwgIlByb2dyZXNzaXZlIiwgIlJlY3VycmVuY2UiLCAieERlY2Vhc2VkIiwgIlNlY29uZCBNYWxpZ25hbmN5IiwgIlVuYXZhaWxhYmxlIikKCnBidGFfZGYgPC0gcmVhZHI6OnJlYWRfdHN2KHBidGFfZmlsZSwgZ3Vlc3NfbWF4ID0gMTAwMDAwLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKSAlPiUgCiAgc2VsZWN0KEtpZHNfRmlyc3RfUGFydGljaXBhbnRfSUQsIEtpZHNfRmlyc3RfQmlvc3BlY2ltZW5fSUQsIGNnX211bHRpcGxlLCBjZ19pZCwgY2dHRkFDLCB0dW1vcl9kZXNjcmlwdG9yKQoKdG1iX3ZhZl9kZiA8LSByZWFkcjo6cmVhZF90c3YodG1iX3ZhZl9maWxlLCBndWVzc19tYXggPSAxMDAwMDAsIHNob3dfY29sX3R5cGVzID0gRkFMU0UpICU+JSAKICBmaWx0ZXIoIXRtYiA+PSAxMCkgJT4lIAogIHNlbGVjdChLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lELCBWYXJpYW50X0NsYXNzaWZpY2F0aW9uLCBnZW5lX3Byb3RlaW4sIG11dGF0aW9uX2NvdW50LAlyZWdpb25fc2l6ZSwgdG1iLCBWQUYpCgpnZW5vbWljX3BhaXJlZF9kZiA8LSByZWFkcjo6cmVhZF90c3YoZ2Vub21pY19wYWlyZWRfZmlsZSwgZ3Vlc3NfbWF4ID0gMTAwMDAwLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKSAlPiUKICBsZWZ0X2pvaW4ocGJ0YV9kZiwgYnkgPSBjKCJLaWRzX0ZpcnN0X1BhcnRpY2lwYW50X0lEIikpICU+JSAKICBsZWZ0X2pvaW4odG1iX3ZhZl9kZiwgYnkgPSBjKCJLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lEIikpICU+JQogIGZpbHRlcighaXMubmEodG1iKSkKCm5vX3NhbXBsZXNfd2l0aF90bWIgPC0gcHJpbnQobGVuZ3RoKHVuaXF1ZShnZW5vbWljX3BhaXJlZF9kZiRLaWRzX0ZpcnN0X1BhcnRpY2lwYW50X0lEKSkpCgojIEF0dGVudGlvbiBhcyBzb21lIGJzIHNwZWNpbWVuIG1pZ2h0IG5vdCBoYXZlIFRNQi4KIyBJZiB0aGF0IGhhcHBlbnMsIHdlIHdpbGwgZW5kIHVwIHdpdGggc2FtcGxlcyBsYWNraW5nIHRpbWVwb2ludHMuCiMgTGV0J3MgaWRlbnRpZnkgdGhlc2Ugc2FtcGxlcyBhbmQgcmVtb3ZlIHRoZW0gZm9yIG5vdy4KCmRmIDwtIGdlbm9taWNfcGFpcmVkX2RmICU+JQogIHNlbGVjdChLaWRzX0ZpcnN0X1BhcnRpY2lwYW50X0lELCB0dW1vcl9kZXNjcmlwdG9yKSAlPiUgCiAgdW5pcXVlKCkgJT4lCiAgYXJyYW5nZShLaWRzX0ZpcnN0X1BhcnRpY2lwYW50X0lELCB0dW1vcl9kZXNjcmlwdG9yKSAlPiUKICBncm91cF9ieShLaWRzX0ZpcnN0X1BhcnRpY2lwYW50X0lEKSAlPiUKICBzdW1tYXJpemUodHVtb3JfZGVzY3JpcHRvcl9zdW0gPSBzdHJfYyh0dW1vcl9kZXNjcmlwdG9yLCBjb2xsYXBzZSA9ICI7IikpICU+JQogIGZpbHRlcighdHVtb3JfZGVzY3JpcHRvcl9zdW0gJWluJSBjKCJEaWFnbm9zaXMiLCAiUHJvZ3Jlc3NpdmUiLCAiUmVjdXJyZW5jZSIsICJTZWNvbmQgTWFsaWduYW5jeSIsICJVbmF2YWlsYWJsZSIsICJEZWNlYXNlZCIsICJQcm9ncmVzc2l2ZTtQcm9ncmVzc2l2ZSIpKSAlPiUKICBsZWZ0X2pvaW4oZ2Vub21pY19wYWlyZWRfZGYsIGJ5ID0gYygiS2lkc19GaXJzdF9QYXJ0aWNpcGFudF9JRCIpKSAlPiUKICBmaWx0ZXIoIWNnX2lkID09ICJOQSIpICU+JSAKICBtdXRhdGUodHVtb3JfZGVzY3JpcHRvciA9IGNhc2Vfd2hlbihncmVwbCgiRGVjZWFzZWQiLCB0dW1vcl9kZXNjcmlwdG9yKSB+ICJ4RGVjZWFzZWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+IHR1bW9yX2Rlc2NyaXB0b3IpLAogICAgICAgICBtYXRjaF9pZCA9IHBhc3RlKHR1bW9yX2Rlc2NyaXB0b3IsIEtpZHNfRmlyc3RfUGFydGljaXBhbnRfSUQsIHNlcCA9ICJfIiksCiAgICAgICAgIHR1bW9yX2Rlc2NyaXB0b3IgPSBmYWN0b3IodHVtb3JfZGVzY3JpcHRvciksCiAgICAgICAgIHR1bW9yX2Rlc2NyaXB0b3IgPSBmY3RfcmVsZXZlbCh0dW1vcl9kZXNjcmlwdG9yLCB0aW1lcG9pbnRzKSkKCm5vX3NhbXBsZXMgPC0gcHJpbnQobGVuZ3RoKHVuaXF1ZShkZiRLaWRzX0ZpcnN0X1BhcnRpY2lwYW50X0lEKSkpCgojIExldCdzIGNvdW50IG51bWJlciBvZiBzYW1wbGVzIApjb3VudF9kZiA8LSBkZiAlPiUgCiAgZ3JvdXBfYnkodHVtb3JfZGVzY3JpcHRvciwgY2dfaWQsIG1hdGNoX2lkLCBWYXJpYW50X0NsYXNzaWZpY2F0aW9uKSAlPiUgCiAgZHBseXI6OmNvdW50KGNnX2lkKSAKCmBgYCAKCiMgRGVmaW5lIHBhcmFtZXRlcnMgZm9yIHBsb3RzCgpgYGB7ciBkZWZpbmUtcGFyYW1ldGVycy1mb3ItcGxvdHN9CiMgUmVhZCBjb2xvciBwYWxldHRlCnBhbGV0dGVfZGYgPC0gcmVhZHI6OnJlYWRfdHN2KHBhbGV0dGVfZmlsZSwgZ3Vlc3NfbWF4ID0gMTAwMDAwLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKSAKCiMgRGVmaW5lIGFuZCBvcmRlciBwYWxldHRlCnBhbGV0dGUgPC0gcGFsZXR0ZV9kZiRoZXhfY29kZXMKbmFtZXMocGFsZXR0ZSkgPC0gcGFsZXR0ZV9kZiRjb2xvcl9uYW1lcwpgYGAKCiMgQWx0ZXJhdGlvbnMgcGVyIHRpbWVwb2ludAoKYGBge3IgcGxvdC10aW1lcG9pbnQsIGZpZy53aWR0aCA9IDYsIGZpZy5oZWlnaHQgPSA2LCBmaWcuZnVsbHdpZHRoID0gVFJVRX0KIyBEZWZpbmUgcGFyYW1ldGVycyBmb3IgZnVuY3Rpb24KeF92YWx1ZSA8LSBjb3VudF9kZiR0dW1vcl9kZXNjcmlwdG9yCnRpdGxlIDwtIHBhc3RlKCJWYXJpYW50IHR5cGVzIGluIFBCVEEgY29ob3J0Iiwgc2VwID0gIiAiKQoKIyBSdW4gZnVuY3Rpb24KZm5hbWUgPC0gcGFzdGUwKHBsb3RzX2RpciwgIi8iLCAiQWx0ZXJhdGlvbl90eXBlX3RpbWVwb2ludHNfYmFycGxvdHMucGRmIikKcHJpbnQoZm5hbWUpCnAgPC0gY3JlYXRlX3N0YWNrZWRfYmFycGxvdF92YXJpYW50KGNvdW50X2RmID0gY291bnRfZGYsIHggPSB4X3ZhbHVlLCBwYWxldHRlID0gcGFsZXR0ZSwgdGl0bGUgPSB0aXRsZSkKcGRmKGZpbGUgPSBmbmFtZSwgd2lkdGggPSA2LCBoZWlnaHQgPSA2KQpwcmludChwKQpkZXYub2ZmKCkKYGBgCgojIEFsdGVyYXRpb25zIHBlciB0aW1lcG9pbnQgaW4gZWFjaCBjYW5jZXIgdHlwZQoKYGBge3IgcGxvdC1jZy1pZCwgZmlnLndpZHRoID0gMjUsIGZpZy5oZWlnaHQgPSAzMCwgZmlnLmZ1bGx3aWR0aCA9IFRSVUV9CiMgRGVmaW5lIHBhcmFtZXRlcnMgZm9yIGZ1bmN0aW9uCnhfdmFsdWUgPC0gY291bnRfZGYkdHVtb3JfZGVzY3JpcHRvcgp0aXRsZSA8LSBwYXN0ZSgiVmFyaWFudCB0eXBlcyBpbiBQQlRBIGNvaG9ydCBhY3Jvc3MgY2FuY2VyIGdyb3VwcyIsIHNlcCA9ICIgIikKcm93cyA8LSA1CgojIFJ1biBmdW5jdGlvbgpmbmFtZSA8LSBwYXN0ZTAocGxvdHNfZGlyLCAiLyIsICJBbHRlcmF0aW9uX3R5cGVfdGltZXBvaW50c19jZ19pZF9iYXJwbG90cy5wZGYiKQpwcmludChmbmFtZSkKcCA8LSBjcmVhdGVfc3RhY2tlZF9iYXJwbG90X3ZhcmlhbnRfY2dfaWQoY291bnRfZGYgPSBjb3VudF9kZiwgeCA9IHhfdmFsdWUsIHBhbGV0dGUgPSBwYWxldHRlLCB0aXRsZSA9IHRpdGxlLCByb3dzID0gcm93cykKcGRmKGZpbGUgPSBmbmFtZSwgd2lkdGggPSAyNSwgaGVpZ2h0ID0gMzApCnByaW50KHApCmRldi5vZmYoKQpgYGAKCgojIEFsdGVyYXRpb25zIHBlciB0aW1lcG9pbnQgaW4gZWFjaCBjYW5jZXIgdHlwZSBhbmQga2lkc19pZAoKYGBge3IgcGxvdC1jZy1pZC1raWRzLCBmaWcud2lkdGggPSAzMCwgZmlnLmhlaWdodCA9IDMwLCBmaWcuZnVsbHdpZHRoID0gVFJVRX0KY2dfaWRfaWQgPC0gYXMuY2hhcmFjdGVyKHVuaXF1ZShjb3VudF9kZiRjZ19pZCkpIApjZ19pZF9pZCA8LSBzb3J0KGNnX2lkX2lkLCBkZWNyZWFzaW5nID0gRkFMU0UpCmNnX2lkX2lkCgojIERlZmluZSBwYXJhbWV0ZXJzIGZvciBmdW5jdGlvbgp4X3ZhbHVlIDwtIGNvdW50X2RmJG1hdGNoX2lkCnRpdGxlIDwtIHBhc3RlKCJWYXJpYW50IHR5cGVzIGluIFBCVEEgY29ob3J0IGFjcm9zcyBjYW5jZXIgZ3JvdXBzIiwgc2VwID0gIiAiKQpyb3dzIDwtIDUKCiMgUnVuIGZ1bmN0aW9uCmZuYW1lIDwtIHBhc3RlMChwbG90c19kaXIsICIvIiwgIkFsdGVyYXRpb25fdHlwZV90aW1lcG9pbnRzX2NnX2lkX2tpZHNfYmFycGxvdHMucGRmIikKcHJpbnQoZm5hbWUpCnAgPC0gY3JlYXRlX3N0YWNrZWRfYmFycGxvdF92YXJpYW50X2NnX2lkKGNvdW50X2RmID0gY291bnRfZGYsIHggPSB4X3ZhbHVlLCBwYWxldHRlID0gcGFsZXR0ZSwgdGl0bGUgPSB0aXRsZSwgcm93cyA9IHJvd3MpCnBkZihmaWxlID0gZm5hbWUsIHdpZHRoID0gMzAsIGhlaWdodCA9IDMwKQpwcmludChwKQpkZXYub2ZmKCkKYGBgCgojIEFsdGVyYXRpb25zIHBlciB0aW1lcG9pbnQgaW4gZWFjaCBjYW5jZXIgdHlwZSBhbmQgdGltZXBvaW50IG1vZGVsCgpgYGB7ciBwbG90LXRpbWVwb2ludC1tb2RlbCwgZmlnLndpZHRoID0gMjAsIGZpZy5oZWlnaHQgPSAxMCwgZmlnLmZ1bGx3aWR0aCA9IFRSVUV9CnRtX2RmX3Bsb3QgPC0gZGYgJT4lCiAgZmlsdGVyKCFpcy5uYSh0aW1lcG9pbnRzX21vZGVscykpICU+JSAKICBncm91cF9ieSh0dW1vcl9kZXNjcmlwdG9yLCBjZ19pZCwgdGltZXBvaW50c19tb2RlbHMsIG1hdGNoX2lkLCBWYXJpYW50X0NsYXNzaWZpY2F0aW9uKSAlPiUgCiAgZHBseXI6OmNvdW50KGNnX2lkKQoKdG0gPC0gYXMuY2hhcmFjdGVyKHVuaXF1ZSh0bV9kZl9wbG90JHRpbWVwb2ludHNfbW9kZWxzKSkKdG0gPC0gc29ydCh0bSwgZGVjcmVhc2luZyA9IEZBTFNFKQp0bQoKIyBMb29wIHRocm91Z2ggdmFyaWFibGUKZm9yIChpIGluIHNlcV9hbG9uZyh0bSkpewogIHByaW50KGkpCiAgZGZfc3ViIDwtIHRtX2RmX3Bsb3QgJT4lCiAgICAgIGZpbHRlcih0aW1lcG9pbnRzX21vZGVscyA9PSB0bVtpXSkKICAKICAjIERlZmluZSBwYXJhbWV0ZXJzIGZvciBmdW5jdGlvbgogIHhfdmFsdWUgPC0gZGZfc3ViJG1hdGNoX2lkCiAgdGl0bGUgPC0gcGFzdGUodG1baV0pCiAgCiAgaWYgKGkgJWluJSBjKDEsMiw2KSl7CiAgICByb3dzIDwtIDIKICAgIH1lbHNlewogICAgICByb3dzIDwtIDEKICAgICAgfQogIAogICMgUnVuIGZ1bmN0aW9uCiAgcCA8LSBjcmVhdGVfc3RhY2tlZF9iYXJwbG90X3ZhcmlhbnRfY2dfaWQoY291bnRfZGYgPSBkZl9zdWIsIHggPSB4X3ZhbHVlLCBwYWxldHRlID0gcGFsZXR0ZSwgdGl0bGUgPSB0aXRsZSwgcm93cyA9IHJvd3MpCiAgCn0KYGBgCgoKYGBge3IgZWNobz1UUlVFfQpzZXNzaW9uSW5mbygpCmBgYAo=